﻿using System;
using System.Globalization;
using GeoAPI.Geometries;

namespace NetTopologySuite.Mathematics
{
	public class Vector3D
	{
		public static double Dot(Coordinate A, Coordinate B, Coordinate C, Coordinate D)
		{
			double num = B.X - A.X;
			double num2 = B.Y - A.Y;
			double num3 = B.Z - A.Z;
			double num4 = D.X - C.X;
			double num5 = D.Y - C.Y;
			double num6 = D.Z - C.Z;
			return num * num4 + num2 * num5 + num3 * num6;
		}

		public static Vector3D Create(double x, double y, double z)
		{
			return new Vector3D(x, y, z);
		}

		public static Vector3D Create(Coordinate coord)
		{
			return new Vector3D(coord);
		}

		public Vector3D(Coordinate v)
		{
			this._x = v.X;
			this._y = v.Y;
			this._z = v.Z;
		}

		public static double Dot(Coordinate v1, Coordinate v2)
		{
			return v1.X * v2.X + v1.Y * v2.Y + v1.Z * v2.Z;
		}

		public Vector3D(Coordinate from, Coordinate to)
		{
			this._x = to.X - from.X;
			this._y = to.Y - from.Y;
			this._z = to.Z - from.Z;
		}

		public Vector3D(double x, double y, double z)
		{
			this._x = x;
			this._y = y;
			this._z = z;
		}

		public double X
		{
			get
			{
				return this._x;
			}
		}

		public double Y
		{
			get
			{
				return this._y;
			}
		}

		public double Z
		{
			get
			{
				return this._z;
			}
		}

		public double Dot(Vector3D v)
		{
			return this._x * v._x + this._y * v._y + this._z * v._z;
		}

		public double Length()
		{
			return System.Math.Sqrt(this._x * this._x + this._y * this._y + this._z * this._z);
		}

		public static double Length(Coordinate v)
		{
			return System.Math.Sqrt(v.X * v.X + v.Y * v.Y + v.Z * v.Z);
		}

		public Vector3D Normalize()
		{
			if (this.Length() > 0.0)
			{
				return this.Divide(this.Length());
			}
			return Vector3D.Create(0.0, 0.0, 0.0);
		}

		private Vector3D Divide(double d)
		{
			return Vector3D.Create(this._x / d, this._y / d, this._z / d);
		}

		public static Coordinate Normalize(Coordinate v)
		{
			double num = Vector3D.Length(v);
			return new Coordinate(v.X / num, v.Y / num, v.Z / num);
		}

		public override string ToString()
		{
			return string.Format(NumberFormatInfo.InvariantInfo, "[{0}, {1}, {2}]", new object[]
			{
				this._x,
				this._y,
				this._z
			});
		}

		private readonly double _x;

		private readonly double _y;

		private readonly double _z;
	}
}
